from pathlib import Path
import os
import logging
import re
from typing import Union, Optional

class AbsolutePathConverter:
    """
    绝对路径转换工具类

    功能特性：
    1. 自动解析 ~ 和环境变量
    2. 处理符号链接和网络路径
    3. 支持严格模式（路径必须存在）
    4. 跨平台路径标准化
    5. UNC路径和Windows长路径支持
    """

    @classmethod
    def convert(
        cls,
        path: Union[str, Path],
        base_dir: Union[str, Path] = None,
        strict: bool = False,
        resolve_symlinks: bool = True
    ) -> Optional[Path]:
        """
        将任意路径转换为绝对路径

        :param path: 输入路径（支持相对路径/环境变量/符号链接）
        :param base_dir: 计算相对路径的基准目录（默认当前目录）
        :param strict: 严格模式（路径必须存在）
        :param resolve_symlinks: 是否解析符号链接
        :return: 标准化绝对路径或None
        """
        try:
            # 预处理输入路径
            processed_path = cls._preprocess_path(path)

            # 构建基础路径
            base_path = cls._get_base_path(base_dir)

            # 生成绝对路径
            abs_path = cls._build_absolute_path(processed_path, base_path)

            # 路径解析和验证
            return cls._validate_path(abs_path, strict, resolve_symlinks)

        except (ValueError, OSError) as e:
            logging.error(f"路径转换失败: {str(e)}")
            return None

    @classmethod
    def _preprocess_path(cls, path: Union[str, Path]) -> str:
        """预处理路径字符串"""
        # 转换Path对象为字符串
        path_str = str(path)

        # 展开环境变量（支持${VAR}和%VAR%格式）
        path_str = os.path.expandvars(path_str)

        # 替换Windows风格斜杠
        return path_str.replace('\\', '/') if os.name == 'nt' else path_str

    @classmethod
    def _get_base_path(cls, base_dir: Union[str, Path] = None) -> Path:
        """获取基准目录"""
        if base_dir:
            return Path(base_dir).resolve()
        return Path.cwd()

    @classmethod
    def _build_absolute_path(cls, path: str, base_path: Path) -> Path:
        """构建绝对路径"""
        # 处理网络路径（Windows UNC）
        if path.startswith('\\\\'):
            return Path(path)

        # 处理根路径
        if path.startswith('/'):
            return Path(path)

        # 处理Windows盘符
        if re.match(r'^[A-Za-z]:/', path):
            return Path(path)

        # 处理主目录缩写
        if path.startswith('~'):
            return Path(path).expanduser()

        # 组合相对路径
        return base_path / path

    @classmethod
    def _validate_path(
        cls,
        path: Path,
        strict: bool,
        resolve_symlinks: bool
    ) -> Path:
        """验证并标准化路径"""
        # 解析符号链接
        final_path = path.resolve() if resolve_symlinks else path.absolute()

        # 严格模式验证
        if strict and not final_path.exists():
            raise FileNotFoundError(f"路径不存在: {final_path}")

        # Windows长路径处理
        if os.name == 'nt':
            return cls._handle_windows_long_path(final_path)

        return final_path

    @staticmethod
    def _handle_windows_long_path(path: Path) -> Path:
        """处理Windows长路径（超过260字符）"""
        try:
            return path.resolve()
        except OSError as e:
            if e.winerror == 3:  # ERROR_PATH_NOT_FOUND
                return Path(f"\\\\?\\{path.resolve()}")
            raise

    @classmethod
    def safe_convert(cls, path: str) -> str:
        """生成安全字符串路径（跨平台兼容）"""
        abs_path = cls.convert(path)
        return abs_path.as_posix() if abs_path else ""
    